package com.calvin.study;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.DoubleSummaryStatistics;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;

import com.calvin.study.entity.Fruits;
import com.calvin.study.entity.Vegetable;

import cn.hutool.json.JSONUtil;

/**
 * https://blog.csdn.net/hu10131013/article/details/108368809
 * @author wh
 */
public class ListTest {

	public static void main(String[] args) {
	
		List<Fruits> fruits = new ArrayList<>();// 存放fruits对象集合
		fruits.add(new Fruits(1L, "红富士苹果", 1, new Double("6.99"), 10));
		fruits.add(new Fruits(2L, "阿克苏苹果", 1, new Double("8.99"), 15));
		fruits.add(new Fruits(3L, "车厘子JJJ", 2, new Double("29.99"), 350));
		fruits.add(new Fruits(4L, "丹东999草莓", 3, new Double("25.99"), 50));
		fruits.add(new Fruits(5L, "红富士苹果", 1, new Double("7.99"), 30));
		fruits.add(new Fruits(6L, "小番茄", 4, new Double("10"), 80));

		List<Vegetable> vegetables = new ArrayList<>();
		vegetables.add(new Vegetable(1L, "小番茄", null, null, null));
		

		
		/**
		 * 按水果品种分组，并统计该水果
		 */
		Map<String, DoubleSummaryStatistics> groupByName = fruits.stream()
				.collect(Collectors.groupingBy(Fruits::getName, Collectors.summarizingDouble(Fruits::getMoney)));
		System.out.println("按水果名称分组 ==>:" + JSONUtil.toJsonStr(groupByName));

		groupByName.forEach((k, v) -> {
			System.out.println("水果：" + k + " 总数量：" + v.getCount());
			System.out.println("水果：" + k + " 总金额：" + v.getSum());
			System.out.println("水果：" + k + " 均价：" + v.getAverage());
			System.out.println("水果：" + k + " 价最贵：" + v.getMax());
			System.out.println("水果：" + k + " 价最低：" + v.getMin());
		});

		/**
		 * List -> Map 需要注意的是： toMap 如果集合对象有重复的key，会报错Duplicate key .... 如：红富士苹果有重复数据
		 * 可以用 (k1,k2)->k1 来设置，如果有重复的key,则保留key1,舍弃key2
		 */
		Map<String, Fruits> fruitMap = fruits.stream()
				.collect(Collectors.toMap(Fruits::getName, f -> f, (k1, k2) -> k1));
		System.out.println(JSONUtil.toJsonStr(fruitMap));

		/**
		 * 集合排序
		 */
		List<Fruits> sortList1 = fruits.stream().sorted(Comparator.comparing(Fruits::getMoney))
				.collect(Collectors.toList());
		System.out.println("按水果金额从小到大排序 ==>:" + sortList1);

		List<Fruits> sortList2 = fruits.stream()
				.sorted(Comparator.comparing(Fruits::getMoney).thenComparing(Fruits::getName))
				.collect(Collectors.toList());
		System.out.println("按水果金额从小到大排序 ==>:" + sortList2);

		/**
		 * 集合过滤
		 */
		List<Fruits> filterList = fruits.stream().filter(f -> f.getName().equals("车厘子JJJ"))
				.collect(Collectors.toList());
		System.out.println(JSONUtil.toJsonStr(filterList));

		fruits.stream().mapToDouble(Fruits::getMoney).sum();
		Double totalMoney = fruits.stream().mapToDouble(Fruits::getMoney).reduce(0, Double::sum);
		//BigDecimal totalMoney2 = fruits.stream().map(Fruits::getMoney).reduce(BigDecimal.ZERO, BigDecimal::add);
		System.out.println("求和计算 totalMoney:" + totalMoney);

		/**
		 * 找到集合中第一个是“车厘子JJJ”的数据
		 * 
		 * orElse(null) 不满足条件则返回null
		 */
		Fruits fruit = fruits.stream().filter(f -> f.getName().equals("车厘子JJJ")).findFirst().orElse(null);
		System.err.println(fruit);

		List<Integer> list = new ArrayList<>();
		for (int i = 0; i < 10; i++) {
			list.add(i);
		}
		list.add(1);
		list.add(2);
		list.add(3);
		list.add(4);

		/**
		 * 集合去重操作
		 */
		List<Integer> newList = list.stream().distinct().collect(Collectors.toList());
		System.out.println("集合去重：" + newList);

		
		/**
		 * 找到集合中重复的元素
		 */
		Map<Integer, Long> countMap = list.stream()
				.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
		// countMap.get(key) > 1就是数量大于1的元素所以是重复的元素
		List<Integer> compareList = countMap.keySet().stream().filter(key -> countMap.get(key) > 1).distinct()
				.collect(Collectors.toList());
		System.out.println("重复的数据：" + compareList.toString());
		
		
		/**
		 * 遍历两个List，将匹配的内容合并
		 * 小番茄即是水果，也是蔬菜的一种，但目前蔬菜中为录入小番茄的价格，种类，数量等，需要我们将水果中小番茄的数据同步到蔬菜中。
		 * 
		 */
		List<Vegetable> vList = vegetables.stream()
				.map(v -> fruits.stream().filter(f -> Objects.equals(v.getName(), f.getName())).findFirst().map(i -> {
					v.setName(i.getName());
					v.setType(i.getType());
					v.setMoney(i.getMoney());
					v.setNum(i.getNum());
					return v;
				}).orElse(null)).filter(Objects::nonNull).collect(Collectors.toList());//.findFirst().get() 这里也可以返回单个对象
		System.out.println(vList);
	}
}
